package com.ruoyi.cs.service.impl;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.domain.vo.AnchorBattleParamReq;
import com.ruoyi.cs.domain.vo.TRobotBehaviorVo;
import com.ruoyi.cs.domain.vo.TUserVo;
import com.ruoyi.cs.mapper.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.impl.SysConfigServiceImpl;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.cs.service.ITUserService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-03-25
 */
@Service
@SuppressWarnings("all")
public class TUserServiceImpl implements ITUserService
{
    private static final Logger log = LoggerFactory.getLogger(TUserServiceImpl.class);
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private TUserTgMapper tUserTgMapper;
    @Autowired
    private TBackpackMapper tBackpackMapper;
    @Autowired
    private TGoodsServiceImpl tGoodsService;
    @Autowired
    private TGoodsMapper tGoodsMapper;
    @Autowired
    private TBoxServiceImpl tBoxService;
    @Autowired
    private TRollServiceImpl tRollService;
    @Autowired
    private TUserSyMapper tUserSyMapper;
    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Autowired
    private TUserAuthenticationMapper tUserAuthenticationMapper;
    @Autowired
    private TRobotBehaviorMapper tRobotBehaviorMapper;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TBoxMapper tBoxMapper;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Value("${token.expireTime}")
    Long expireTime;

    @Autowired
    private RedisCache redisCache;

    @Value("${ruoyi.picpath}")
    private String picpath;
    @Value("${ruoyi.cos-fileUrl}")
    private String cosfileUrl;

    /**
     * 查询用户信息
     * 
     * @param userId 用户信息ID
     * @return 用户信息
     */
    @Override
    public TUser selectTUserById(String userId)
    {
        return tUserMapper.selectTUserById(userId);
    }

    /**
     * 查询用户信息列表
     * 
     * @param tUser 用户信息
     * @return 用户信息
     */
    @Override
    public List<TUser> selectTUserList(TUser tUser)
    {
        return tUserMapper.selectTUserList(tUser);
    }
    /**
     * 新增用户信息
     * 
     * @param tUser 用户信息
     * @return 结果
     */
    @Override
    public Response insertTUser(TUser user)
    {
        TUser user1 = null;
        if (StringUtils.isNotEmpty(user.getUserPromotersId()))
        {
//            user1 = tUserMapper.getUserInfoByCode(user.getUserPromotersCode());
            user1 = tUserMapper.selectTUserById(user.getUserPromotersId());
            if (user1 == null) {
                return Response.fail(Constants.FAILCODE,"推广人推广码错误！");
            }
        }
        TUser user3 = null;
        if (StringUtils.isNotEmpty(user.getUserSelfCode()))
        {
            if (!(user.getUserSelfCode().length()>=1 && user.getUserSelfCode().length()<=16)) {
                return Response.fail(Constants.FAILCODE,"本人推广码字符长度限制在1-16位！");
            }
            user3 = tUserMapper.getUserInfoByCode(user.getUserSelfCode());
            if (user3 != null) {
                return Response.fail(Constants.FAILCODE,"本人推广码重复！");
            }

        }
        if (StringUtils.isEmpty(user.getUserPhone())) {
            return Response.fail(Constants.FAILCODE,"手机号不能为空！");
        }
        /**判断手机号是否存在*/
        TUser user2 = tUserMapper.getUserInfoByPhone(user.getUserPhone());
        if (user2 != null) {
            return Response.fail(Constants.FAILCODE,"手机号已存在！");
        }

        //插入用户表中
        String userId = IdUtils.fastUUID().substring(0,8)+DateUtils.dateTimeNow();
        user.setUserId(userId);
        user.setUserSelfCode(StringUtils.isNotEmpty(user.getUserSelfCode()) ? user.getUserSelfCode() : IdUtils.fastUUID().substring(0,8));
        user.setUserType(Constants.USERTYPE1);
        user.setUserTotalRecharge(new BigDecimal(0));
        user.setCreateTime(DateUtils.getNowDate());
        user.setUserPwd(Md5Utils.hash(user.getUserPwd()));
        user.setCommissionRatio(new BigDecimal(0.15));
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        user.setUserIp(ip);
        user.setUserArea(AddressUtils.getRealAddressNameByIP(ip));

        if (StringUtils.isEmpty(user.getUserPic())) {
            List<String> pics = Arrays.asList(Constants.USERPICS);
            Random random = new Random();
            int index = random.nextInt(pics.size());
            user.setUserPic(picpath +cosfileUrl+ pics.get(index));
        }
        String userseed = HashUtil.generateUserSeed();
        user.setUserSeed(userseed);
        int count =  tUserMapper.insertTUser(user);

        //插入用户推广信息记录表
        if (count > 0 && user1 != null) {
            TUserTg tg = new TUserTg();
            tg.setUserId(user1.getUserId());
            tg.setTgUserId(userId);
            tg.setCreateTime(DateUtils.getNowDate());
            tUserTgMapper.insertTUserTg(tg);
        }
        return Response.success();
    }

    /**
     * 修改用户信息
     * 
     * @param tUser 用户信息
     * @return 结果
     */
    @Override
    public Response updateTUser(TUser tUser)
    {
        int row = tUserMapper.updateAnchorTUser(tUser);
        return row > 0 ? Response.success() : Response.fail("用户版本已更新迭代，修改失败");
    }

    /**
     * 批量删除用户信息
     * 
     * @param userId 需要删除的用户信息ID
     * @return 结果
     */
    @Override
    public int deleteTUserByIds(String userId)
    {
        String[] ids = userId.split(",");
        return tUserMapper.batchDeleteTUserByIds(ids);
    }

    /**
     * 删除用户信息信息
     * 
     * @param userId 用户信息ID
     * @return 结果
     */
    @Override
    public int deleteTUserById(String userId)
    {
        return tUserMapper.deleteTUserById(userId);
    }

    /**
     * 启用、停用用户信息
     * @param delFlag
     * @param userId 用户信息ID
     * @return
     */
    @Override
    public int updateDelFlagTUserByIds(String delFlag, String userId) {
        return tUserMapper.updateDelFlagTUserByIds(delFlag,userId);
    }

    /**
     * 用户注册
     * @param user
     * @return
     * @throws Exception
     */
    @Override
    public Response  register(TUser user) throws Exception {

        if (!(StringUtils.isNotEmpty(user.getUserPhone()) && StringUtils.isNotEmpty(user.getUserPwd()))) {
            return Response.fail(Constants.FAILCODE, "用户手机号、密码不能为空!");
        }
        if (user.getUserPwd().length() < 6 || user.getUserPwd().length() > 14) {
            return Response.fail(Constants.FAILCODE, "密码长度最小6位最大14位~");
        }
        //判断用户手机号是否已经注册
        TUser phoneUser = tUserMapper.getUserInfoByPhone(user.getUserPhone());
        if (phoneUser != null) {
            return Response.fail(Constants.FAILCODE, "用户手机号已注册!");
        }

        if (StringUtils.isNotEmpty(user.getUserName()) && user.getUserName().length() > 8) {
            return Response.fail(Constants.FAILCODE, "昵称长度不能大于8位!");
        }

        if (StringUtils.isEmpty(user.getUserName())) {
            user.setUserName(Constants.USERNAME_PREFIX + CommonUtils.generateRandomString(5));
        }
        if (!StringUtils.isSpecialChar(user.getUserName())) {
            return Response.fail(Constants.FAILCODE, "昵称不能包含特殊字符!");
        }
        TUser user1 = tUserMapper.getUserInfoByUserName(user.getUserName());
        if (user1 != null) {
            return Response.fail(Constants.FAILCODE, "用户昵称已注册!");
        }

        TUser tgUser = null;
        boolean flag = false;
        //判断该用户是否填写邀请码,并判断邀请码是否正确
        if (StringUtils.isNotEmpty(user.getTgUserSelfCode())) {
            tgUser = tUserMapper.getUserInfoByCode(user.getTgUserSelfCode());
            if (tgUser == null) {
                return Response.fail(Constants.FAILCODE, "注册失败，邀请码填写错误!");
            }
            if (tgUser.getDelFlag().equals(Constants.SUCCESS) && (!tgUser.getUserType().equals(2))) {
                flag = true;
            } else {
                return Response.fail(Constants.FAILCODE, "邀请码已过时!");
            }
        }
        //短信验证码前缀
        String key = Constants.PHONE_CODE + user.getUserPhone();
        //从Redis获取短信验证码
        String code = redisCache.getCacheObject(key);
        if (code == null || "".equals(code) || !code.equals(user.getCode())) {
            return Response.fail(Constants.FAILCODE, "验证码错误或无效!");
        }
        redisCache.deleteObject(key);

        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        user.setUserIp(ip);
        user.setUserArea(AddressUtils.getRealAddressNameByIP(ip));

        /**现在统一IP地址注册*/
        Long ipusernum = tUserMapper.countUserNumByIP(ip);
        String limitnum = sysConfigService.selectConfigByKey("ip_limit_register");
        limitnum = limitnum == null ? "1" : limitnum;
        if(ipusernum.intValue() > Integer.parseInt(limitnum) ){
            log.error("防止机器人恶意注册：ip:{},地区:{}",ip,AddressUtils.getRealAddressNameByIP(ip));
            return Response.fail(Constants.FAILCODE, "防止机器人恶意注册，注册失败!");
        }

        //插入用户表中
        String userId = IdUtils.fastUUID().substring(0,8)+DateUtils.dateTimeNow();
//        String userSelfCode = IdUtils.fastUUID().substring(0, 8);
        String userSelfCode = HashUtil.generatePromoCode();
        while (tUserMapper.isPromoCodeExists(userSelfCode) >  0){
            userSelfCode = HashUtil.generatePromoCode();
        }
        user.setUserId(userId);
        user.setUserSelfCode(userSelfCode);
        user.setUserType(Constants.USERTYPE0);
        user.setUserBalance(new BigDecimal(0));
        user.setPurchaseQuota(new BigDecimal(0));
        user.setUserTotalRecharge(new BigDecimal(0));
        user.setCreateTime(DateUtils.getNowDate());
        user.setUserPwd(Md5Utils.hash(user.getUserPwd()));
        user.setIsBattle(Constants.SUCCESS);
        if (StringUtils.isEmpty(user.getUserPic())) {
            List<String> pics = Arrays.asList(Constants.USERPICS);
            Random random = new Random();
            int index = random.nextInt(pics.size());
            user.setUserPic(picpath +cosfileUrl+ pics.get(index));
        }

        user.setCommissionRatio(new BigDecimal(0.04));
        user.setUserUrl(Constants.USERURLPREFIX+"/"+userSelfCode);
        /**设置推广人推广码*/
        if (tgUser != null && StringUtils.isNotEmpty(tgUser.getUserSelfCode())) {
            user.setUserPromotersId(tgUser.getUserId());
        }
        user.setUserSeed(HashUtil.generateUserSeed());
        int count =  tUserMapper.insertTUser(user);

        //验证码正确则插入用户推广信息记录表
        if (count > 0 && flag) {
            TUserTg tg = new TUserTg();
            tg.setUserId(tgUser.getUserId());
            tg.setTgUserId(userId);
            tg.setCreateTime(DateUtils.getNowDate());
            tUserTgMapper.insertTUserTg(tg);
        }
        return Response.success();
    }

    /**
     * 判断手机号是否存在
     * @param userphone
     * @return
     */
    @Override
    public Response decidePhone(String userphone) {
        TUser tUser = tUserMapper.getUserInfoByPhone(userphone);
        if (tUser != null) {
            return Response.fail(Constants.FAILCODE,"手机号已注册!");
        }
        return Response.success();
    }

    /**
     * 通过手机号修改密码
     * @param userphone
     * @param code
     * @param password
     * @return
     */
    @Override
    public Response retrievePassword(String userphone, String code, String password) {
        if(password.length() < 6 || password.length() > 14){
            return Response.fail(Constants.FAILCODE,"密码长度最小6位最大14位~");
        }
        //短信验证码前缀
        String key = Constants.PHONE_CODE+userphone;
        //从Redis获取短信验证码
        String note = redisCache.getCacheObject(key);
        if (code == null || "".equals(code) || !code.equals(note)) {
            return Response.fail(Constants.FAILCODE,"验证码错误或无效!");
        }
        redisCache.deleteObject(key);
        TUser tUser = tUserMapper.getUserInfoByPhone(userphone);
        if (tUser == null || !tUser.getDelFlag().equals(Constants.SUCCESS)) {
            return Response.fail(Constants.FAILCODE,"用户不存在或已冻结!");
        }
        tUser.setUserPwd( Md5Utils.hash(password));
        tUser.setUpdateTime(DateUtils.getNowDate());
        int count = tUserMapper.updatePassword(tUser);
        if (count > 0){
            return Response.success();
        }else {
            return Response.fail(Constants.FAILCODE,"重置密码失败!");
        }
    }

    /**
     * 短信验证码发送
     * @param userphone
     * @return
     */
    @Override
    public Response sendNode(String userphone) {
        String note = VerifyCodeUtils.generateVerifyCode(6, "0123456789");
        /**短信发送  配置需要修改*/
        String result = null;
        try {
            Map map = SendSms.sendCode(userphone, note);
            if (map.get("Code") != null && map.get("Code").equals(Constants.CODE_0)) {
                result = map.get("Code").toString();
            }else if (map.get("Code").equals("InternalError.Timeout")) {
                return Response.fail(Constants.FAILCODE, "请求下发短信超时!");
            } else if (map.get("Code").equals("UnauthorizedOperation.RequestIpNotInWhitelist")) {
                return Response.fail(Constants.FAILCODE, "请求IP不在白名单中!");
            } else if (map.get("Code").equals("InvalidParameterValue.IncorrectPhoneNumber")) {
                return Response.fail(Constants.FAILCODE, "手机号格式错误!");
            } else if (map.get("Code").equals("LimitExceeded.DailyLimit")) {
                return Response.fail(Constants.FAILCODE, "当日下发条数超过设定的上限 !");
            } else if (map.get("Code").equals("LimitExceeded.PhoneNumberDailyLimit")) {
                return Response.fail(Constants.FAILCODE, "当前手机号发送短信条数超过当日上限!");
            } else if (map.get("Code").equals("LimitExceeded.PhoneNumberOneHourLimit")) {
                return Response.fail(Constants.FAILCODE, "当前手机号1小时内发送短信条数超过上限，请稍后重试!");
            } else {
                return Response.fail(Constants.FAILCODE, "发送短信异常!");
            }
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            return Response.fail(Constants.FAILCODE,"发送短信异常!");
        }
        if (result == null) {
            return Response.fail(Constants.FAILCODE, "手机号码错误!");
        }
        if (Constants.CODE_0.equals(result)) {
            String key = Constants.PHONE_CODE + userphone;
            redisCache.setCacheObject(key, note, 5, TimeUnit.MINUTES);
        } else {
            return Response.fail(Constants.FAILCODE, "手机号填写错误，不存在此手机号!");
        }
        return Response.success();
    }

    /**
     * 修改用户基本信息
     * @param user
     * @return
     */
    @Override
    public Response updateUserName(String userId,String userName) {
        /**判断用户昵称是否已经存在*/
        if(StringUtils.isEmpty(userName)){
            return Response.fail("昵称不能为空!");
        }
        if(!StringUtils.isSpecialChar(userName)){
            return Response.fail(Constants.FAILCODE,"昵称不能包含特殊字符！");
        }
        if (userName.length() > 8) {
            return Response.fail(Constants.FAILCODE,"昵称长度不能大于8位~");
        }
        int count = tUserMapper.getCountByUserName(userName,userId);
        if (count > 0) {
            return  Response.fail(Constants.FAILCODE,"用户昵称已存在!");
        }
        tUserMapper.updateUserName(userId,userName);
        return Response.success();
    }

    /**
     * 修改用户交易链接
     * @param tUser
     * @return
     */
    @Override
    public Response updateUserUrl(TUser tUser) {
        //短信验证码前缀
//        String key = Constants.PHONE_CODE+tUser.getUserPhone();
        //从Redis获取短信验证码
//        String note = redisCache.getCacheObject(key);
//        if (tUser.getCode() == null || "".equals(tUser.getCode()) || !tUser.getCode().equals(note)) {
//            return new AjaxResult(Constants.FAILCODE,"验证码错误或无效!");
//        }
//        redisCache.deleteObject(key);
        tUser.setSteamID(tUser.getSteamID().trim());
        tUser.setUpdateTime(DateUtils.getNowDate());
        if (StringUtils.isNotEmpty(tUser.getSteamID()) && !tUser.getSteamID().startsWith(Constants.STEAMPREFIX)) {
            return Response.fail(Constants.FAILCODE, "链接格式错误或为空！");
        }
        TUser tUser1 = tUserMapper.getUserInfoByPhone(tUser.getUserPhone());
        if (tUser1 == null || !tUser1.getDelFlag().equals("0")) {
            return Response.fail(Constants.FAILCODE, "账号冻结或不存在！");
        }
        if (StringUtils.isNotEmpty(tUser.getSteamID()) && StringUtils.isNotEmpty(tUser1.getSteamID()) && tUser1.getSteamID().equals(tUser.getSteamID())) {
            return Response.fail("您已绑定该链接，无需重复绑定！");
        }
        if (StringUtils.isNotEmpty(tUser.getSteamID())) {
            Long steamIdIsExist = tUserMapper.checkSteamIdIsExist(tUser.getSteamID());
            if (steamIdIsExist > 0l) {
                return Response.fail("该steamid已绑定其他账号");
            }
        }
//            if(StringUtils.isNotEmpty(tUser.getSteamID())){
//                Map<String, String> mapflag = commonService.steamInfo(tUser.getSteamID());
//                if (mapflag.get("flag").equals("false")) {
//                    return Response.fail(Constants.FAILCODE, "steam交易链接错误");
//                }
//            }
//        if (StringUtils.isNotEmpty(tUser1.getSteamID())){
//            return Response.fail(Constants.FAILCODE,"交易链接不能重复绑定，如需解绑请进行反馈！");
//        }

        int count = tUserMapper.updateTUserSteamId(tUser);
        if (count > 0) {
            return Response.success();
        } else {
            return Response.fail(Constants.FAILCODE, "操作失败！");
        }

    }

    /**
     * 后台获取用户推广详情
     * @param userSelfCode
     * @return
     */
    @Override
    public List<TUser> getUserTGList(String userId) {
        return tUserMapper.getUserTGList(userId);
    }

    /**
     * 后台用户展示列表
     * @param tUser
     * @return
     */
    @Override
    public List<TUserVo> userListBack(TUserVo tUser) {
        List<TUserVo> list = tUserMapper.userListBack(tUser);
        if(list != null && list.size()>0){
            /**用户ID*/
            List<String> userIds = list.stream().map(TUser::getUserId).collect(Collectors.toList());

            /**获取用户时间段内充值*/
            List<Map> recharmonemap = tUserMapper.rechargeMoney(userIds,tUser.getStartTime(),tUser.getEndTime());

            /**获取用户带动充值*/
            List<Map> lowerRechargeMoneyMap = tUserMapper.lowerRechargeMoney(userIds,tUser.getStartTime(),tUser.getEndTime());

            /**拉新人数*/
            List<Map> promoteNumMap = tUserMapper.promoteNum(userIds,tUser.getStartTime(),tUser.getEndTime());

            /**拉新取回价值*/
            List<Map> lowerRetrieveMoneyMap = tUserMapper.lowerRetrieveMoney(userIds,tUser.getStartTime(),tUser.getEndTime());

            /**拉新背包价值*/
            List<Map> lowerPackMoney = tUserMapper.lowerPackMoney(userIds);

            /**拉新背包价值*/
            List<Map> lowerBalanceTotalMoney = tUserMapper.lowerBalanceTotalMoney(userIds);

            /**用户取回背包总价值*/
            List<Map> retrievedTotalPrice = tBackpackMapper.retrievedPriceGroupByUserId(userIds);

            SysConfig gen_config = sysConfigMapper.checkConfigKeyUnique("general_user_retrieve_limit_parameters");
            String general_user_retrieve_limit_parameters_val = gen_config == null ? "1" : gen_config.getConfigValue();


            for (TUserVo tUserVo : list) {
                if(recharmonemap.size()>0){
                    List<Map> map = recharmonemap.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal rechargeMoney =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("rechargeMoney").toString());
                    tUserVo.setRechargeMoney(rechargeMoney);
                }else {
                    tUserVo.setRechargeMoney(new BigDecimal(0));
                }
                if(lowerRechargeMoneyMap.size()>0){
                    List<Map> map = lowerRechargeMoneyMap.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal lowerRechargeMoney =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("lowerRechargeMoney").toString());
                    tUserVo.setLowerRechargeMoney(lowerRechargeMoney);
                }else {
                    tUserVo.setLowerRechargeMoney(new BigDecimal(0));
                }

                if(promoteNumMap.size()>0){
                    List<Map> map = promoteNumMap.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    long promoteNum =  map.size() == 0 ? 0l : Long.parseLong(map.get(0).get("promoteNum").toString());
                    tUserVo.setPromoteNum(promoteNum);
                }else {
                    tUserVo.setPromoteNum(0l);
                }

                if(lowerPackMoney.size()>0){
                    List<Map> map = lowerPackMoney.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal lowerPackMoney1 =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("lowerPackMoney").toString());
                    tUserVo.setLowerPackMoney(lowerPackMoney1);
                }else {
                    tUserVo.setLowerPackMoney(new BigDecimal(0));
                }

                if(lowerRetrieveMoneyMap.size()>0){
                    List<Map> map = lowerRetrieveMoneyMap.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal lowerRetrieveMoney =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("lowerRetrieveMoney").toString());
                    tUserVo.setLowerRetrieveMoney(lowerRetrieveMoney);
                }else {
                    tUserVo.setLowerRetrieveMoney(new BigDecimal(0));
                }

                if(lowerBalanceTotalMoney.size()>0){
                    List<Map> map = lowerBalanceTotalMoney.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal lowerUserBalance =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("lowerUserBalance").toString());
                    tUserVo.setLowerBalanceMoney(lowerUserBalance);
                }else {
                    tUserVo.setLowerBalanceMoney(new BigDecimal(0));
                }

                if(retrievedTotalPrice.size()>0){
                    List<Map> map = retrievedTotalPrice.stream().filter(bean -> bean.get("userId").toString().equals(tUserVo.getUserId())).collect(Collectors.toList());
                    BigDecimal totalPrice =  map.size() == 0 ? new BigDecimal(0) : new BigDecimal(map.get(0).get("totalPrice").toString());
                    tUserVo.setRetrievedMoney(totalPrice);
                }else {
                    tUserVo.setRetrievedMoney(new BigDecimal(0));
                }

                /**剩余取回额度*/
                BigDecimal totalCzf = tUserVo.getUserTotalRecharge().multiply(new BigDecimal(general_user_retrieve_limit_parameters_val)).setScale(2,BigDecimal.ROUND_HALF_UP);
                totalCzf = totalCzf.add(tUserVo.getExtraQuota());
                totalCzf = totalCzf.subtract(tUserVo.getHistoryRecoveryQuota());
                tUserVo.setRemainingWithdrawalLimit(totalCzf);
            }

        }
        return list;
    }

    @Override
    public TUser getUserByPhone(String userphone) {
        return tUserMapper.getUserInfoByPhone(userphone);
    }

    @Override
    public Long getTgCountByUserId(String userId) {
        return tUserMapper.getTgCountByUserId(userId);
    }

    @Override
    public Map userCount(String startTime, String endTime) {
        return tUserMapper.userCount(startTime, endTime);
    }

    @Override
    public Response updateInvitationCode(String userId, String tgUserSelfCode) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser.getUserSelfCode().equals(tgUserSelfCode)) {
            return Response.fail(Constants.FAILCODE, "不能绑定本人推广码！");
        }

//        if (tUser.getCreateTime().compareTo(DateUtils.getBeforeHourTime(72)) < 0 && StringUtils.isEmpty(tUser.getUserPromotersId())) {
//            return Response.fail(Constants.FAILCODE, "注册已超过72小时，不可绑定！");
//        }
        /*推广用户*/
        TUser tgUser = tUserMapper.getUserInfoByCode(tgUserSelfCode);
        if (StringUtils.isNull(tgUser)) {
            return Response.fail(Constants.FAILCODE, "邀请码错误！");
        }

        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())) {
            TUser oldtUser = tUserMapper.selectTUserById(tUser.getUserPromotersId());
            if ("0".equals(oldtUser.getAnchorResignationStatus())){
                return Response.fail(Constants.FAILCODE, "不能重复设置邀请码！");
            }
        }

        int count = tUserMapper.updateInvitationCode(tgUser.getUserId(), tUser.getUserId());
        if (count > 0) {
            return Response.success();
        } else {
            return Response.fail(Constants.FAILCODE, "邀请码修改失败!");
        }
    }

    /**
     * 合作伙伴
     * @param userId
     * @return
     */
    @Override
    public Response<Map> cooperativePartner(String userId) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        /**获取总邀请人数*/
        Long tgtotal = tUserTgMapper.tgTotal(tUser.getUserId());
        /**获取推广总充值和今日充值*/
        String czMoneyToday = tRechargeMapper.myTgRechargeToday(tUser.getUserId());
        String czMoneyTotal = tRechargeMapper.myTgRechargeTotal(tUser.getUserSelfCode());
        /**总佣金*/
        Map tgTotal = tUserSyMapper.tgSyTotal(userId);
        Map map = new HashMap();
        map.put("tgTotal",tgtotal);
        map.put("czMoneyToday",czMoneyToday);
        map.put("czMoneyTotal",czMoneyTotal);
        map.put("tgSytotal",tgTotal.get("tgSyTotal"));
        map.put("tgZczTotal",tgTotal.get("tgZczTotal"));
        return Response.success(map);
    }

    @Override
    public int updateBattlePower(String userId, String isBattle) {
        return tUserMapper.updateBattlePower(userId,isBattle);
    }

    @Override
    public List<TGoodsUpgrate> myGoodsUpgrateRecord(String userId) {
        return tUserMapper.myGoodsUpgrateRecord(userId);
    }

    @Override
    public Response authentication(String idcard, String realname, String code, String phone, TUser tUser) {
        if (StringUtils.isEmpty(idcard) || StringUtils.isEmpty(realname)) {
            return Response.fail(Constants.FAILCODE, "身份证、姓名必填！");
        }
        if (tUser == null) {
            return Response.fail(Constants.FAILCODE, "用户不存在！");
        }
        if (!"0".equals(tUser.getDelFlag())) {
            return Response.fail(Constants.FAILCODE, "用户冻结，请联系管理员处理！");
        }
        if (Constants.SUCCESS.equals(tUser.getIsAuthentication())) {
            return Response.fail(Constants.FAILCODE, "已实名认证，请勿重复操作！");
        }
        if (!CommonUtils.isIDNumber(idcard)) {
            return Response.fail(Constants.FAILCODE, "身份证号码格式错误！");
        }
        //短信验证码前缀
        String key = Constants.PHONE_CODE + phone;
        //从Redis获取短信验证码
        String code1 = redisCache.getCacheObject(key);
        if (code1 == null || "".equals(code1) || !code1.equals(code)) {
            return Response.fail(Constants.FAILCODE, "验证码错误或无效!");
        }
        redisCache.deleteObject(key);
        try {
            int age = DateUtils.getAge(idcard.substring(6, 14));
            if (age < 18) {
                return Response.fail(Constants.FAILCODE, "抱歉，您未满18岁，实名认证失败");
            }
        } catch (Exception e) {
            log.error("身份证出生年月异常:{}", e.getMessage());
            return Response.fail(Constants.FAILCODE, "身份证异常!");
        }
        /**实名认证信息*/
        TUserAuthentication tUserAuthentication = new TUserAuthentication();
        tUserAuthentication.setUserId(tUser.getUserId());
        tUserAuthentication.setIdcard(idcard);
        tUserAuthentication.setIdcardTime(idcard.substring(6, 14));
        tUserAuthentication.setRealname(realname);
        tUserAuthentication.setCreateTime(new Date());

        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("authentication_binding_limit");
        long limitnum = sysConfig == null ? 5 : Long.parseLong(sysConfig.getConfigValue());
        long num = tUserAuthenticationMapper.countByIdcard(idcard);
        if (num >= limitnum) {
            return Response.fail(Constants.FAILCODE, "该身份证绑定账号过多");
        }

        idcard = Md5Utils.hash(idcard.toUpperCase());
        realname = Md5Utils.hash(realname);
        String param = "key=" + Constants.authenticationkey + "&idcard=" + idcard + "&realname=" + realname + "&orderid=1";
        String response = HttpUtils.sendGet("http://op.juhe.cn/idcard/queryMd5", param);
        JSONObject jsonObject = JSONObject.parseObject(response);
        if ("0".equals(jsonObject.getString("error_code"))) {/**为0 表示请求成功*/
            JSONObject resultObject = jsonObject.getJSONObject("result");
            if ("1".equals(resultObject.getString("res"))) {
                log.info("实名认证：{}", resultObject.toJSONString());
                tUser.setIsAuthentication(Constants.SUCCESS);
                tUserMapper.updateTUser(tUser);

                /**插入实名认证信息*/
                tUserAuthentication.setOrderid(resultObject.getString("orderid"));
                tUserAuthenticationMapper.insertTUserAuthentication(tUserAuthentication);
            } else {
                return Response.fail(Constants.FAILCODE, "身份信息不匹配！");
            }
        } else {
            return CommonUtils.error_code(jsonObject.getString("error_code"));
        }
        return Response.success("实名认证成功");
    }

    /**
     * 添加机器人
     * @param userName 昵称
     * @param balance 金额
     * @return
     */
    @Override
    public Response addRobot(TUser tUser) {

        String ss = tUserMapper.getRobotMaxPhone();
        Long userPhone = 10000000000L;
        if (StringUtils.isNotEmpty(ss)) {
            userPhone = Long.parseLong(ss);
            userPhone++;
        }
        if(StringUtils.isEmpty(tUser.getUserName())){
            return Response.fail("昵称不能为空!");
        }
        if(!StringUtils.isSpecialChar(tUser.getUserName())){
            return Response.fail(Constants.FAILCODE,"昵称不能包含特殊字符！");
        }
        if (tUser.getUserName().length() > 8) {
            return Response.fail(Constants.FAILCODE,"昵称长度不能大于8位~");
        }
        /**判断用户昵称是否已经存在*/
        int userCount = tUserMapper.getCountByUserName(tUser.getUserName(),null);
        if (userCount > 0) {
            return  Response.fail(Constants.FAILCODE,"用户昵称已存在!");
        }
        if(tUser.getUserBalance() == null){
            tUser.setUserBalance(new BigDecimal(1000000));
        }
        if (tUser.getUserBalance().compareTo(BigDecimal.ZERO) < -1 || tUser.getUserBalance().compareTo(new BigDecimal(1000000)) > 0) {
            return Response.fail("金币数量须在0-1000000之间!");
        }
        String userId = IdUtils.fastUUID().substring(0,8)+DateUtils.dateTimeNow();
        tUser.setUserId(userId);
        if(StringUtils.isEmpty(tUser.getUserType())){
            tUser.setUserType(Constants.USERTYPE2);
        }
        if (StringUtils.isEmpty(tUser.getUserPic())) {
            List<String> pics = Arrays.asList(Constants.USERPICS);
            Random random = new Random();
            int index = random.nextInt(pics.size());
            tUser.setUserPic(picpath +cosfileUrl+ pics.get(index));
        }
        tUser.setUserPhone(StringUtils.isNotEmpty(tUser.getUserPhone()) ? tUser.getUserPhone() : userPhone.toString());
        tUser.setIsRetrieve(Constants.FAIL);
        tUser.setCreateTime(DateUtils.getNowDate());
        tUser.setIsBattle(Constants.SUCCESS);
        String userseed = HashUtil.generateUserSeed();
        tUser.setUserSeed(userseed);
        int count = tUserMapper.insertTUser(tUser);
        if (count < 1){
            return Response.fail("新增失败!");
        }
        return Response.success();
    }

    @Override
    public Response editRobot(TUser tUser) {
        tUser.setUpdateTime(DateUtils.getNowDate());
        if(StringUtils.isEmpty(tUser.getUserName())){
            return Response.fail("昵称不能为空!");
        }
        if(!StringUtils.isSpecialChar(tUser.getUserName())){
            return Response.fail(Constants.FAILCODE,"昵称不能包含特殊字符！");
        }
        if (tUser.getUserName().length() > 8) {
            return Response.fail(Constants.FAILCODE,"昵称长度不能大于8位~");
        }
        int userCount = tUserMapper.getCountByUserName(tUser.getUserName(), tUser.getUserId());
        if (userCount > 0) {
            return  Response.fail(Constants.FAILCODE,"用户昵称已存在!");
        }
        if(tUser.getUserBalance() == null){
            tUser.setUserBalance(new BigDecimal(1000000));
        }
        if (tUser.getUserBalance().compareTo(BigDecimal.ZERO) < -1 || tUser.getUserBalance().compareTo(new BigDecimal(1000000)) > 0) {
            return Response.fail("金币数量须在0-1000000之间!");
        }

        if (StringUtils.isEmpty(tUser.getUserPic())) {
            List<String> pics = Arrays.asList(Constants.USERPICS);
            Random random = new Random();
            int index = random.nextInt(pics.size());
            tUser.setUserPic(picpath +cosfileUrl+ pics.get(index));
        }

        int i = tUserMapper.updateRobot(tUser);
        if(i<1){
            return Response.fail("操作失败!");
        }
        return Response.success();
    }

    /**
     * 机器人行为设置
     *
     * @param tRobotBehaviorVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response robotBehavior(TRobotBehaviorVo tRobotBehaviorVo) {
        if (StringUtils.isEmpty(tRobotBehaviorVo.getXwType())) {
            return Response.fail(Constants.FAILCODE, "参数不能为空！");
        }
        String type = tRobotBehaviorVo.getXwType();
        TRobotBehavior tRobotBehavior = new TRobotBehavior();
        if (type.equals(Constants.GOOGSBLTYPE0)) { /**箱子*/
            if (StringUtils.isNull(tRobotBehaviorVo.getExecuteNum()) || tRobotBehaviorVo.getExecuteNum() < 1 || tRobotBehaviorVo.getExecuteNum() > 100) {
                return Response.fail(Constants.FAILCODE, "执行次数区间为1-100！");
            }
            /**箱子不存在是则随机箱子随机饰品*/
            if (StringUtils.isNotEmpty(tRobotBehaviorVo.getBoxId())) {
                TBox tBox = tBoxService.getInfoTbox(tRobotBehaviorVo.getBoxId());
                /**饰品不存在是默认随机、存在时指定开启*/
                if (StringUtils.isNotEmpty(tRobotBehaviorVo.getGoodsId())) {
                    /**获取饰品信息*/
                    TGoods tGoods = tGoodsMapper.selectTGoodsById(tRobotBehaviorVo.getGoodsId());
                    int num = tGoods.getGoodsChance().multiply(new BigDecimal(10000)).intValue();
                    List<TBackpack> backpackList = new ArrayList<>();
                    for (int i = 0; i < tRobotBehaviorVo.getExecuteNum(); i++) {
                        /**指定饰品插入背包*/
                        String bbId = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
                        TBackpack backpack = new TBackpack();
                        backpack.setBbId(bbId);
                        backpack.setUserId(tRobotBehaviorVo.getUserId());
                        backpack.setGoodsId(tRobotBehaviorVo.getGoodsId());
                        if(Constants.BOXTYPE0.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE0);
                        }else if(Constants.BOXTYPE2.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE8);
                        }else if(Constants.BOXTYPE3.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE9);
                        }else if(Constants.BOXTYPE4.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE12);
                        }else if(Constants.BOXTYPE5.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE13);
                        }else if(Constants.BOXTYPE6.equals(tBox.getBoxType())){
                            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE14);
                        }else {
                            return Response.fail("不存在该箱子类型");
                        }
                        backpack.setGoodsBelongingId(tRobotBehaviorVo.getBoxId());
                        backpack.setGoodsPrice(tGoods.getGoodsPrice());
                        backpack.setGoodsExprice(tGoods.getGoodsExprice());
                        backpack.setBbStatus(Constants.BBSTATUS0);
                        backpack.setAuditStatus(Constants.AUDITSTATUS0);
                        backpack.setDelFlag(Constants.SUCCESS);
                        backpack.setCreateTime(DateUtils.getNowDate());
                        backpack.setGoodsNum(1);
                        backpack.setGoodsType(tGoods.getGoodsType());
                        backpack.setOpenBeforeBalance(new BigDecimal(0));
                        backpack.setOpenAfterBalance(new BigDecimal(0));
                        backpack.setOpenBoxPrice(new BigDecimal(0));
                        backpack.setGoodsBelongingName(tBox.getBoxName());
                        backpack.setBbGoodsName(tGoods.getGoodsName());
                        backpack.setBbGoodsPic(tGoods.getGoodsPic());
                        backpack.setBbGoodsGrate(tGoods.getGoodsGrate());
                        backpackList.add(backpack);
                    }
                    tBackpackMapper.insertTBackpackBatch(backpackList);
                    tRobotBehavior.setSecondTargetId(tRobotBehaviorVo.getGoodsId());
                    tRobotBehavior.setSecondTargetName(tGoods.getGoodsName());
                } else {
                    /**正常开箱*/
                    try {
                        Response response = tBoxService.robotUnpacking(tRobotBehaviorVo.getUserId(), tRobotBehaviorVo.getBoxId(), tRobotBehaviorVo.getExecuteNum());
                        if (response.getCode() == Constants.FAILCODE || response.getCode() == 500) {
                            return response;
                        }
                    } catch (Exception e) {
                        return Response.fail(Constants.FAILCODE, "设置开箱异常");
                    }
                    tRobotBehavior.setSecondTargetName("随机");
                }
                /**行为记录*/
                tRobotBehavior.setXwTargetId(tRobotBehaviorVo.getBoxId());
                //TBox tBox = tBoxService.getInfoTbox(tRobotBehaviorVo.getBoxId());
                tRobotBehavior.setXwTargetName(tBox.getBoxName());
                tRobotBehavior.setExecuteNum(tRobotBehaviorVo.getExecuteNum());
            } else {
                //箱子不存在时则随机箱子随机饰品
                //查询出箱子列表
                TBox tBox = new TBox();
                tBox.setDelFlag(Constants.SUCCESS);
                tBox.setBoxType(Constants.BOXTYPE0);
                List<TBox> boxList = tBoxMapper.selectTBoxList(tBox);
                if (boxList.size() < 1) {
                    return Response.fail(Constants.FAILCODE, "可执行的随机箱子列表为空！");
                }
                Collections.shuffle(boxList);
                Random random = new Random();
                TBox randomBox = boxList.get(random.nextInt(boxList.size() - 1));
                tRobotBehaviorVo.setBoxId(randomBox.getBoxId());
                tRobotBehaviorVo.setBoxName(randomBox.getBoxName());
                /**正常开箱*/
                try {
                    Response response = tBoxService.robotUnpacking(tRobotBehaviorVo.getUserId(), tRobotBehaviorVo.getBoxId(), tRobotBehaviorVo.getExecuteNum());
                    if (response.getCode() == Constants.FAILCODE || response.getCode() == 500) {
                        return response;
                    }
                } catch (Exception e) {
                    return Response.fail(Constants.FAILCODE, "设置开箱异常");
                }
                tRobotBehavior.setSecondTargetName("随机");
                /**行为记录*/
                tRobotBehavior.setXwTargetId(tRobotBehaviorVo.getBoxId());
                //TBox tBox = tBoxService.getInfoTbox(tRobotBehaviorVo.getBoxId());
                tRobotBehavior.setXwTargetName(randomBox.getBoxName());
                tRobotBehavior.setExecuteNum(tRobotBehaviorVo.getExecuteNum());
            }

        } else if (type.equals(Constants.GOOGSBLTYPE1)) {/**ROLL房*/
            Response response = tRollService.joinRollRobot(tRobotBehaviorVo.getRollId(), tRobotBehaviorVo.getUserId(), null);

            if (response.getCode() == Constants.FAILCODE || response.getCode() == 500) {
                return response;
            }
            tRobotBehavior.setXwTargetId(tRobotBehaviorVo.getRollId());
            TRoll tRoll = tRollService.selectTRollById(tRobotBehaviorVo.getRollId());

            tRobotBehavior.setXwTargetName(tRoll.getRollName());
        }
        tRobotBehavior.setUserId(tRobotBehaviorVo.getUserId());
        tRobotBehavior.setXwType(tRobotBehaviorVo.getXwType());
        tRobotBehavior.setCreateTime(DateUtils.getNowDate());
        tRobotBehaviorMapper.insertTRobotBehavior(tRobotBehavior);
        return Response.success();
    }

    @Override
    public List<TRobotBehavior> selectTRobotBehaviorList(TRobotBehavior tRobotBehavior) {
        return tRobotBehaviorMapper.selectTRobotBehaviorList(tRobotBehavior);
    }

    @Override
    public List<TUser> selectUserList(TUser tUser) {
        return tUserMapper.selectUserList(tUser);
    }

    @Override
    public Long registeredNumber(String userType) {
        return tUserMapper.registeredNumber(userType);
    }

    @Override
    public Long checkSteamIdIsExist(String steamID) {
        return tUserMapper.checkSteamIdIsExist(steamID);
    }

    @Override
    public int battleRobotBalanceRecover() {
        return tUserMapper.battleRobotBalanceRecover();
    }

    @Override
    public List<Map<String,Object>> robatNumber() {
        return tUserMapper.robatNumber();
    }

    @Override
    public List<TUser> selectBattleRobot(String userBalance) {
        return tUserMapper.selectBattleRobot(userBalance);
    }

    @Override
    public int updateAnchorResignationStatus(String userId, String anchorResignationStatus) {
        return tUserMapper.updateAnchorResignationStatus(userId,anchorResignationStatus);
    }

    @Override
    public List<String> getPTandZBUserList() {
        return tUserMapper.getPTandZBUserList();
    }

    /**
     * 分组统计VIP人数
     * @return
     */
    @Override
    public List<Map<String,Object>> groupCountVipNum() {
        return tUserMapper.groupCountVipNum();
    }

    /**
     * @Desc: 设置客户端种子
     * @author: zz
     * @date: 2023/12/4
     */
    @Override
    public Boolean setUserSeed(String userId, String userSeed) {
        int row = tUserMapper.setUserSeed(userId, userSeed);
        return row > 0 ? true : false;
    }

    /**
     * @Desc: 主播对战参数设置
     * @author: zz
     * @date: 2024/2/22
     */
    @Override
    public Response anchorBattleParamReq(String userId, AnchorBattleParamReq req) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        if(tUser == null || !tUser.getUserType().equals(Constants.USERTYPE1)){
            return Response.fail("用户不存在或非主播");
        }
        if(req.getIsFanBattleEnabled()){
            if(req.getSingleBattleLimit() == null || req.getTotalBattleLimit() == null || req.getDailyFreeBattleCount() == null){
                return Response.fail("主播创建粉丝对战开启情况下，下面的参数都必填");
            }
        }
        tUser.setIsFanBattleEnabled(req.getIsFanBattleEnabled());
        tUser.setSingleBattleLimit(req.getSingleBattleLimit());
        tUser.setTotalBattleLimit(req.getTotalBattleLimit());
        tUser.setDailyFreeBattleCount(req.getDailyFreeBattleCount());
        tUser.setDailyRechargeAmount(req.getDailyRechargeAmount());
        tUser.setTotalRechargeAmount(req.getTotalRechargeAmount());
        tUser.setIsFollowBattleEnabled(req.getIsFollowBattleEnabled());
        tUserMapper.updateAnchorBattleParam(tUser);
        return Response.success();
    }
}
